package com.invengo.module_check.data.repsitory.business.source.impl;


import android.annotation.SuppressLint;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;

import com.blankj.utilcode.util.TimeUtils;
import com.google.gson.Gson;
import com.invengo.base.http.RetrofitClient;
import com.invengo.base.http.RobotRxUtils;
import com.invengo.base.utils.BeanMapperUtils;
import com.invengo.base.utils.RequestBodyUtils;
import com.invengo.library_db.BuildConfig;
import com.invengo.library_db.GreenDaoManager;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.BookCarBean;
import com.invengo.library_db.entity.module_check.offline.LogBean;
import com.invengo.library_db.entity.module_check.RecordBean;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_db.entity.module_check.StructBean;
import com.invengo.module_check.data.api.BusinessApi;
import com.invengo.module_check.data.entity.AnalyzeBean;
import com.invengo.module_check.data.repsitory.business.source.BusinessSource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.http.BaseBean;
import me.goldze.mvvmhabit.http.NoDataException;
import me.goldze.mvvmhabit.http.UpdateResult;
import me.goldze.mvvmhabit.http.interceptor.logging.LocalLogUtil;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;

//网络实现
public class HttpBusinessSourceImpl implements BusinessSource {
    private BusinessApi businessApi;

    public HttpBusinessSourceImpl() {
        businessApi = RetrofitClient.getInstance().create(BusinessApi.class);
    }

    @Override
    public void removeByBooks(List<BookBean> bookBeans) {

    }

    @Override
    public Observable<BaseBean<BookBean>> getBookByTid(String tid) {
        switch (BuildConfig.CUSTOM_MADE){
            case "ShangHai_TengHui_TuShuGuan":
//                String newTid = HEXTransUtils.string2Bytes(tid);
                String newTid = tid;
                LocalLogUtil.temp2File(tid+"   转换后的tid值   "+newTid);
                return businessApi.getBookByTid(newTid)
                        .subscribeOn(Schedulers.single())
                        .flatMap((Function<BaseBean<BookBean>, ObservableSource<BaseBean<BookBean>>>) bookBeanBaseBean -> {
                            if (bookBeanBaseBean.getData()==null)
                                throw new NoDataException(10000);
                            return Observable.just(bookBeanBaseBean);
                        })
                        .retryWhen(throwable -> throwable
                                .flatMap((Function<Throwable, ObservableSource<BaseBean<AnalyzeBean>>>) throwable1 -> {
                                    if (throwable1 instanceof NoDataException){
                                        HashMap<String,Object> params = new HashMap<>();
                                        params.put("mark","上海声阅");
                                        params.put("libCode","BSBLSX");
                                        params.put("label",tid);
                                        params.put("userdata","");
                                        return    businessApi.analyzeBoarCode(RequestBodyUtils.parse(params)).subscribeOn(Schedulers.io());
                                    }else{
                                        return Observable.error(throwable1);
                                    }
                                })
                                .map(new RxUtils.HandleFuc<>())/**/
                                .flatMap((Function<AnalyzeBean, ObservableSource<BaseBean<UpdateResult>>>) analyzeBean -> {
                                    List<BookBean> bookBeans = new ArrayList<>();
                                    BookBean bean =new BookBean();
                                    bean.setTid(analyzeBean.getLabel());//tid
                                    bean.setBarCode(analyzeBean.getBarCode());//barcode
                                    bean.setBookName(analyzeBean.getTitle());//书名
                                    bean.setLocationName(analyzeBean.getLocation());//馆藏地
                                    bean.setSzISBN(analyzeBean.getIsbn());//isbn
                                    bean.setSzAuthor(analyzeBean.getAuthor());//作者
                                    bookBeans.add(bean);
                                    HashMap<String,Object> bookList = new HashMap<>();
                                    bookList.put("bookInfoList",bookBeans);
                                    return businessApi.registerBook(RequestBodyUtils.parse(bookList)).subscribeOn(Schedulers.io());
                                })
                                .flatMap((Function<BaseBean<UpdateResult>, ObservableSource<String>>) updateResultBaseBean -> {
                                    if (updateResultBaseBean.isOk()){
                                        return Observable.just("注册成功");
                                    }else{
                                      return   Observable.error(new IllegalArgumentException("注册失败"));
                                    }
                                }).subscribeOn(Schedulers.io()));
            default:
                return businessApi.getBookByTid(tid);
        }
    }


    @Override
    public Observable<BaseBean<BookBean>> getBookByCode(String code) {
        return businessApi.getBookByCode(code)
                .flatMap((Function<BaseBean<BookBean>, ObservableSource<BaseBean<BookBean>>>) bookBeanBaseBean -> {
                    if (bookBeanBaseBean.getData()==null)
                        throw new NoDataException(10000);
                    return Observable.just(bookBeanBaseBean);
                })
                .retryWhen(new RxUtils.RetryNoBook(businessApi.registerBook(RequestBodyUtils.parse(newCode->{
                    List<BookBean> bookBeans = new ArrayList<>();
                    BookBean bean =new BookBean();
                    bean.setBarCode((String) newCode);
                    bookBeans.add(bean);
                    HashMap<String,Object> bookList = new HashMap<>();
                    bookList.put("bookInfoList",bookBeans);
                    return bookList;
                },code)),1,600));
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getShelfInfoByCode(String shelfCode) {
        return businessApi.getShelfInfoByCode(shelfCode);
    }

    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByShelfCode(String shelfCode) {
        return businessApi.getBookByShelfCode(shelfCode);
    }

    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByMultiShelf(String startCode, String endCode,String BookCountlimit) {
        return businessApi.getBookByMultiShelf(startCode, endCode,BookCountlimit);
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getShelfInfoByTid(String tid) {
        return businessApi.getShelfInfoByTid(tid);
    }

    @Override
    public Observable<BaseBean<ShelfBean>> getNextOrUpperShelf(String shelfCode, boolean isNext) {
        return businessApi.getNextOrUpperShelf(shelfCode, isNext);
    }
    @Override
    public Observable<BaseBean<List<BookBean>>> getBookByKeyword(String keyword, Integer pageIndex, Integer pageSize) {
        return businessApi.getBookByKeyword(keyword, pageIndex, pageSize);
    }
    @Override
    public Observable<BaseBean<List<ShelfBean>>> getShelfList(String shelfCode) {
        return businessApi.getShelfList(shelfCode.substring(0, 12));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> forceRevokeBook(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("nUpdateType", 0);
        return businessApi.forceRevokeBook(RequestBodyUtils.parse(params));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> forcePositioning(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        for (BookBean bean : bookBeans) {
            bean.setOldShelfCode(bean.getShelfCode());
            bean.setOldShelfName(bean.getShelfName());
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("desbookcaseno", shelfCode);//目标架位号
        return businessApi.forcePositioning(RequestBodyUtils.parse(params));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> bookListing(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookInfoList", bookBeans);
        params.put("operateType", 0);
        return businessApi.updateBookInfo(RequestBodyUtils.parseWithAnd(params));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> inventoryBook(List<BookBean> bookBeans, String currentShelfCode, String currentShelfName, int errorCount, int inshelfCount, int borrowCount, int notOnCount) {
        HashMap<String, Object> params = new HashMap<>();
        LogBean logBean = new LogBean();
        logBean.setBorrowCount(borrowCount);
        logBean.setInshelfCount(inshelfCount);
        logBean.setErrorCount(errorCount);
        logBean.setNotOnCount(notOnCount);
        logBean.setDateTime(TimeUtils.getNowString());
        logBean.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        logBean.setShelfCode(currentShelfCode);
        List<BookBean> flowBookBeans = BeanMapperUtils.transFlowBookBean(bookBeans, currentShelfCode, currentShelfName, false);
        for (BookBean flowBookBean : flowBookBeans) {
            KLog.e(flowBookBean.getBookName()+" " + flowBookBean.getTip()+" "+flowBookBean.getNPDStatus()+ " 外借状态： "+ flowBookBean.getState());
        }
        params.put("inventorylog", logBean);
        params.put("checkedRecds", flowBookBeans);
        return businessApi.inventoryBook(RequestBodyUtils.parseWithAnd(params));
    }


    @Override
    public Observable<BaseBean<UpdateResult>> parallelLogs(List<BookBean> bookBeans, String currentShelfCode, String currentShelfName, int errorCount, int inshelfCount, int borrowCount, int notOnCount) {
        HashMap<String, Object> params = new HashMap<>();
        LogBean logBean = new LogBean();
        logBean.setBorrowCount(borrowCount);
        logBean.setInshelfCount(inshelfCount);
        logBean.setErrorCount(errorCount);
        logBean.setNotOnCount(notOnCount);
        logBean.setDateTime(TimeUtils.getNowString());
        logBean.setUserId((Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        logBean.setShelfCode(currentShelfCode);
        List<BookBean> beans = BeanMapperUtils.transFlowBookBean(bookBeans, currentShelfCode, currentShelfName, true);
        params.put("parallellog", logBean);
        params.put("checkedrecds", beans);
        return businessApi.parallelLogs(RequestBodyUtils.parseWithAnd(params));
    }


    @Override
    public Observable<BaseBean<UpdateResult>> downBook(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("operateType", 1);
        return businessApi.updateBookInfo(RequestBodyUtils.parseWithAnd(params));
    }


    @Override
    public Observable<BaseBean<UpdateResult>> insertBookDeleteLogs(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("staffid", ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return businessApi.insertBookDeleteLogs(RequestBodyUtils.parseWithAnd(params));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> removeOld(List<BookBean> bookBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("staffid", (Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return businessApi.removeOld(RequestBodyUtils.parseWithAnd(params));
    }



    @Override
    public Observable<BaseBean<UpdateResult>> updateFirstBook(List<ShelfBean> shelfBeans) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("LayerList", new Gson().toJson(shelfBeans));
        return businessApi.updateFirstBook(RequestBodyUtils.parse(params));
    }


    @Override
    public Observable<BaseBean<UpdateResult>> createupdatetask(String startcode, String endcode) {
        String opeartionId = String.valueOf(ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return businessApi.createupdatetask(opeartionId, startcode, endcode);
    }

    @Override
    public Observable<BaseBean<BookCarBean>> getBookCarInfo(String carId) {
//        return businessApi.getBookCarInfo(carId);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().getBookCarbyId(carId), "我找不到这个书车");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> bindBook2Car(List<BookBean> beans, String carId) {
        String booids = StreamSupport.stream(beans) .map(BookBean::getBarCode).reduce("", (s, s2) -> TextUtils.isEmpty(s) ? s + s2 : s + ";" + s2);
        HashMap<String, Object> params = new HashMap<>();
        params.put("carrino", carId);
        params.put("szbookid", booids);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().bindBook2Car(beans, carId), "绑定不成功。。");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> upBook2ShelfFromCar(List<BookBean> beans, String carId) {
        String booids = StreamSupport.stream(beans) .map(BookBean::getBarCode).reduce("", (s, s2) -> TextUtils.isEmpty(s) ? s + s2 : s + ";" + s2);
        HashMap<String, Object> params = new HashMap<>();
        params.put("carrino", carId);
        params.put("szbookid", booids);
        return RxUtils.bindLocal(GreenDaoManager.getInstance().upBook2ShelfFromCar(beans, carId), "图书排架上架出错");
    }

    @Override
    public Observable<BaseBean<UpdateResult>> listingGuide(List<BookBean> beans) {
        Integer StaffID = (Integer) ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID);
        String userName = ACache.getInstance().getAsString(AKey.CACHE_USERNAME);
        for (BookBean bean : beans) {
            bean.setUserId(StaffID);
            bean.setUserName(userName);
            bean.setOpeationDate(TimeUtils.getNowString());
        }
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookrecords", beans);
        return businessApi.listingGuide(RequestBodyUtils.parseWithAnd(params));
    }


    @Override

    public Observable<BaseBean<UpdateResult>> changeShelf(List<BookBean> bookBeans, String shelfCode, String shelfName) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("operateType", 2);
        return businessApi.updateBookInfo(RequestBodyUtils.parseWithAnd(params));
    }

    @Override
    public Observable<BaseBean<UpdateResult>> changeShelfLog(List<BookBean> bookBeans, String shelfCode) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("bookinfolist", bookBeans);
        params.put("desbookcaseno", shelfCode);
        params.put("nstaffid", ACache.getInstance().getAsObject(AKey.CACHE_USER_STAFF_ID));
        return businessApi.changeShelfLog(RequestBodyUtils.parseWithAnd(params));
    }

    @Override
    public Observable<BaseBean<List<ShelfBean>>> getErrorShelf(String startcode, String endcode) {
        return businessApi.getErrorShelf(startcode, endcode);
    }

    @Override
    public Observable<BaseBean<RecordBean>> getUpdateRecordList(int finishstatus, int pageindex, int pagesize) {
        return businessApi.getUpdateRecordList(finishstatus, pageindex, pagesize);
    }

    @Override
    public List<StructBean> getStructData() {
        return null;
    }
}
